﻿//using FrameServer.Net;
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Threading;
//using System.Threading.Tasks;

//namespace FrameServer
//{
//    class Battle
//    {
//        public int battleID;
//        public int mode;
//        public int randomSeed;
//        //对局内所有玩家的UID
//        private readonly List<int> UIDs = new List<int>();
//        //该战局中的每个玩家是否已经准备好//uid-ready
//        private readonly Dictionary<int, bool> dictBattleReady = new Dictionary<int, bool>();
//        //每个玩家的信息//uid-battleUserInfo
//        private readonly Dictionary<int, BattleUserInfo> dictBattleUserInfo = new Dictionary<int, BattleUserInfo>();

//        private BattleStatus BattleStatus = BattleStatus.None;

//        private int frameID;//服务器下发的帧数据的id，从1开始，每下发一次就+1

//        //记录当前帧的所有玩家操作，kv: uid-PlayerOperation
//        private readonly Dictionary<int, PlayerOperation> dictFrameOperation = new Dictionary<int, PlayerOperation>();
//        private static readonly object _lock = new object();
//        // 用来记录一局中所有玩家的帧操作，丢帧处理用，kv: frameID-list
//        private readonly Dictionary<int, List<PlayerOperation>> dictGameOperation = new Dictionary<int, List<PlayerOperation>>();


//        public void CreateBattle(int mode, int battleID, List<MatchPlayerEntity> clientsInBattle, int randomSeed)
//        {
//            this.mode = mode;
//            this.battleID = battleID;
//            this.randomSeed = randomSeed;

//            foreach(MatchPlayerEntity item in clientsInBattle)
//            {
//                int uid = item.uid;
//                int role = item.role;
//                UIDs.Add(uid);
//                dictBattleReady.Add(uid, false);
//                //UDPServer.Instance.CreateNewRcvThread();

//                BattleUserInfo battleUserInfo = new BattleUserInfo
//                {
//                    Uid = uid,
//                    BattleID = battleID,
//                    Role = role
//                };
//                dictBattleUserInfo.Add(uid, battleUserInfo);
//            }

//            BattleEnter battleEnter = new BattleEnter();
//            battleEnter.AllPlayers.AddRange(dictBattleUserInfo.Values);
//            //send message
//            foreach (int uid in UIDs) {
//                battleEnter.Seed = randomSeed;
//                battleEnter.BattleID = battleID;
//                battleEnter.Mode = mode;
//                TCPServer.Instance.GetTcpPeer(uid)?.SendTcpMsg(S2CCode.BattleEnter, battleEnter);
//            }

//            //创建对局后，过一段时间自动销毁对局
//            Task.Run(async () =>
//            {
//                for (int i = 0; i < 60 * 20; i++)
//                {
//                    if(BattleStatus == BattleStatus.Over)
//                        return;
//                    await Task.Delay(1000);
//                }
//                foreach (int uid in UIDs)
//                    TCPServer.Instance.GetTcpPeer(uid)?.SendTcpMsg(S2CCode.ResponseGameOver, new Empty());
//                DestroyBattle();
//            });

//            this.BattleStatus = BattleStatus.Created;
//            //服务器这边对局的创建就基本完成了(Created)，接下来就是等待所有的客户端的Ready
//            //再开一个计时器，如果有客户端过长时间没有发送Ready就先用Poll判断是否断连
//            //如果断连就直接开启对局，如果不是那就说明有客户端还在加载，就再等一会
//            Task.Run(async()=> {
//                await Task.Delay(1000 * 10);//等几秒钟
//                if (BattleStatus < BattleStatus.Started)//说明还有Ready没收到
//                {
//                    foreach (int uid in UIDs)
//                    {
//                        if (TCPServer.Instance.GetTcpPeer(uid) == null || !TCPServer.Instance.GetTcpPeer(uid).IsConnected()) {
//                            //说明有人断连了
//                            LogUtil.Log($"uid为{uid}的玩家在加载过程中断开了连接，将直接BeginBattle");
//                            BeginBattle();
//                            return;
//                        }
//                    }
//                    //说明没人断连，是有玩家还在加载，再等几秒钟
//                    await Task.Delay(1000 * 5);
//                    LogUtil.Log($"某玩家因加载超时，不予等待，将直接BeginBattle");
//                    BeginBattle();
//                }
//            });
//        }

//        //接收到了玩家准备好的消息
//        public void RcvReady(int uid)
//        {           
//            if (BattleStatus >= BattleStatus.Started)
//            {
//                //如果对局已经开始，单独给他发送BattleStart
//                BattleStart battleStart = new BattleStart();
//                TCPServer.Instance.GetTcpPeer(uid)?.SendTcpMsg(S2CCode.BattleStart, battleStart);
//                LogUtil.Log($"battleID:{battleID}-对局已经开始!");
//                return;
//            }
//            dictBattleReady[uid] = true;
//            bool allReady = true;
//            foreach(bool value in dictBattleReady.Values)
//            {
//                if (value == false)
//                {
//                    allReady = false;
//                    break;
//                }
//            }
//            if(allReady == true)
//            {
//                BeginBattle();
//            }
//        }

//        //所有的玩家都已经准备好啦~初始化一些数据，并告诉他们可以上传帧数据(BattleStart)，同时开始下发帧数据
//        private void BeginBattle()
//        {
//            if (BattleStatus >= BattleStatus.Started)
//            {
//                LogUtil.Log("对局已经开始，无需再次BeginBattle");
//                return;
//            }

//            BattleStatus = BattleStatus.Started;

//            foreach (int uid in UIDs) {
//                dictFrameOperation[uid] = new PlayerOperation();
//            }

//            //向对局内所有玩家发送BattleStart
//            BattleStart battleStart = new BattleStart();
//            foreach(int uid in UIDs)
//                TCPServer.Instance.GetTcpPeer(uid)?.SendTcpMsg(S2CCode.BattleStart, battleStart);

//            new Thread(Thread_SendFrameData).Start();
//        }

//        private void Thread_SendFrameData()
//        {
//            LogUtil.Log($"battleID:{battleID}-〇〇〇开始广播帧数据〇〇〇");
//            while (BattleStatus == BattleStatus.Started)
//            {
//                frameID++;
//                DownPlayerOperations frameData = new DownPlayerOperations();
//                lock (_lock)
//                    frameData.PlayerOperations.AddRange(dictFrameOperation.Values);
//                frameData.FrameID = frameID;
//                foreach (int uid in UIDs)
//                    TCPServer.Instance.GetTcpPeer(uid)?.SendUdpMsg(S2CCode.DownPlayerOperations, frameData);
//                dictGameOperation[frameID] = new List<PlayerOperation>(dictFrameOperation.Values);

//                Thread.Sleep(ServerConfig.frameTime);
//            }

//            LogUtil.Log($"battleID:{battleID}-XXX帧数据发送线程结束XXX");
//        }

//        public void RcvPlayerOperation(UpPlayerOperation upPlayerOperation)
//        {
//            int mesID = upPlayerOperation.MesID;
//            PlayerOperation playerOperation = upPlayerOperation.PlayerOperation;
//            int uid = playerOperation.BattleUserInfo.Uid;
//            lock (_lock)
//                dictFrameOperation[uid] = playerOperation;
//        }

//        public void RcvRequestLackFrames(RequestLackFrames requestLackFrames)
//        {
//            int uid = requestLackFrames.BattleUserInfo.Uid;
//            List<int> lackFrameIDs = new List<int>(requestLackFrames.LackFrameIDs);
//            ResponseLackFrames responseLackFrames = new ResponseLackFrames();
//            foreach(int frameID in lackFrameIDs)
//            {
//                DownPlayerOperations downFrameData = new DownPlayerOperations();
//                downFrameData.FrameID = frameID;
//                downFrameData.PlayerOperations.AddRange(dictGameOperation[frameID]);
//                responseLackFrames.LackFrames.Add(downFrameData);
//            }

//            TCPServer.Instance.GetTcpPeer(uid)?.SendUdpMsg(S2CCode.ResponseLackFrames, responseLackFrames);
//        }

//        public void RcvGameOver(RequestGameOver requestGameOver)
//        {
//            foreach (int uid in UIDs)
//                TCPServer.Instance.GetTcpPeer(uid)?.SendTcpMsg(S2CCode.ResponseGameOver, new Empty());
//            DestroyBattle();
//        }

//        public void RcvReenter(int uid)
//        {
//            ReenterResponse reenterResponse = new ReenterResponse
//            {
//                Result = true,
//                BattleID = this.battleID,
//                Seed = this.randomSeed,
//                Mode = this.mode,
//            };
//            reenterResponse.AllPlayers.AddRange(dictBattleUserInfo.Values);

//            TCPServer.Instance.GetTcpPeer(uid)?.SendTcpMsg(S2CCode.ReenterResponse, reenterResponse);
//        }

//        /// <summary>销毁对局，移除自身在BattleMgr中的相关引用，并释放所有资源</summary>
//        private void DestroyBattle() {
//            if (BattleStatus == BattleStatus.Over)
//                return;
//            BattleStatus = BattleStatus.Over;

//            foreach (int uid in UIDs)
//                BattleMgr.Instance.RemoveUser(uid);
//            BattleMgr.Instance.RemoveBattle(this.battleID);

//            dictBattleReady.Clear();
//            dictBattleUserInfo.Clear();
//            dictFrameOperation.Clear();
//            dictGameOperation.Clear();
//            UIDs.Clear();
//            GC.Collect();
//        }
//    }
//    public enum BattleStatus { 
//        None,//初始状态
//        Created,//玩家匹配成功，对局刚被创建
//        Started,//所有玩家已准备完毕，对局已开始
//        Over//对局已结束，马上被销毁
//    }
//}
